SPB Git
2.0 KB · 21 lines tsx
1"use client";2import { useState } from "react";3export function UploadForm({ paperId, csrf, nextNo }: { paperId: string; csrf: string; nextNo: number }) {4  const [msg, setMsg] = useState<string | null>(null); const [busy, setBusy] = useState(false);5  const onSubmit = async (e: React.FormEvent<HTMLFormElement>) => {6    e.preventDefault(); setBusy(true); setMsg(null); const fd = new FormData(e.currentTarget);7    try { const r = await fetch("/api/admin/upload", { method: "POST", body: fd, headers: { "x-csrf-token": csrf } }); const j = await r.json(); if (!r.ok) throw new Error(j.error ?? r.statusText); setMsg(`Uploaded ${j.label} (sha256 ${String(j.sha256).slice(0, 12)}…). Processing queued.`); setTimeout(() => location.reload(), 1200); }8    catch (err) { setMsg("Error: " + (err as Error).message); } finally { setBusy(false); }9  };10  return (<form onSubmit={onSubmit} className="grid sm:grid-cols-[1fr_8rem_10rem_1fr_auto] gap-2 items-end text-sm">11    <input type="hidden" name="paper_id" value={paperId} />12    <label className="block"><span className="label">PDF</span><input type="file" name="file" accept="application/pdf" required className="input mt-1 !py-1.5" /></label>13    <label className="block"><span className="label">Label</span><input name="label" defaultValue={`v${nextNo}`} className="input mt-1" /></label>14    <label className="block"><span className="label">Date (YYYY-MM[-DD])</span><input name="released_on" className="input mt-1" /></label>15    <label className="block"><span className="label">Description</span><input name="description" className="input mt-1" placeholder="Revised manuscript" /></label>16    <label className="flex items-center gap-2 pb-2"><input type="checkbox" name="make_current" defaultChecked /> current</label>17    <button className="btn btn-primary btn-sm sm:col-span-5 justify-self-start" disabled={busy}>{busy ? "Uploading…" : "Upload version"}</button>18    {msg && <p className="sm:col-span-5 text-xs text-fg-2">{msg}</p>}19  </form>);20}21
Files · main
Menu

Theme